#!/bin/bash

# LingShu 多架构Docker镜像构建脚本
# 支持AMD64、ARM64、ARM等多种架构

set -euo pipefail

# 脚本配置
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
VERSION=${VERSION:-"1.0.0"}

# 镜像配置
IMAGE_NAME=${IMAGE_NAME:-"lingshu/lingshu"}
REGISTRY=${REGISTRY:-""}
DOCKERFILE=${DOCKERFILE:-"Dockerfile.optimized"}

# 支持的架构
PLATFORMS=${PLATFORMS:-"linux/amd64,linux/arm64,linux/arm/v7"}

# 构建目标
BUILD_TARGET=${BUILD_TARGET:-"production"}

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 显示横幅
show_banner() {
    echo "=================================="
    echo "  LingShu 多架构镜像构建工具"
    echo "=================================="
    echo "版本: ${VERSION}"
    echo "构建日期: ${BUILD_DATE}"
    echo "Git提交: ${GIT_COMMIT}"
    echo "支持架构: ${PLATFORMS}"
    echo "构建目标: ${BUILD_TARGET}"
    echo "=================================="
    echo
}

# 检查依赖
check_dependencies() {
    log_info "检查构建依赖..."
    
    # 检查Docker
    if ! command -v docker &> /dev/null; then
        log_error "Docker未安装或不在PATH中"
        exit 1
    fi
    
    # 检查Docker版本
    DOCKER_VERSION=$(docker version --format '{{.Server.Version}}' 2>/dev/null || echo "unknown")
    log_info "Docker版本: ${DOCKER_VERSION}"
    
    # 检查buildx插件
    if ! docker buildx version &> /dev/null; then
        log_error "Docker buildx插件未安装"
        log_info "请运行: docker buildx install"
        exit 1
    fi
    
    # 检查Git
    if ! command -v git &> /dev/null; then
        log_warning "Git未安装，将使用默认提交信息"
    fi
    
    log_success "依赖检查完成"
}

# 设置buildx构建器
setup_buildx() {
    log_info "设置Docker buildx构建器..."
    
    # 创建新的构建器实例
    BUILDER_NAME="lingshu-builder"
    
    if docker buildx ls | grep -q "${BUILDER_NAME}"; then
        log_info "使用现有构建器: ${BUILDER_NAME}"
        docker buildx use "${BUILDER_NAME}"
    else
        log_info "创建新构建器: ${BUILDER_NAME}"
        docker buildx create --name "${BUILDER_NAME}" --driver docker-container --use
    fi
    
    # 启动构建器
    docker buildx inspect --bootstrap
    
    log_success "构建器设置完成"
}

# 构建镜像
build_images() {
    log_info "开始构建多架构镜像..."
    
    cd "${PROJECT_ROOT}"
    
    # 构建参数
    local build_args=(
        "--platform=${PLATFORMS}"
        "--target=${BUILD_TARGET}"
        "--build-arg=VERSION=${VERSION}"
        "--build-arg=BUILD_DATE=${BUILD_DATE}"
        "--build-arg=GIT_COMMIT=${GIT_COMMIT}"
        "--file=${DOCKERFILE}"
    )
    
    # 添加标签
    local tags=(
        "${IMAGE_NAME}:${VERSION}"
        "${IMAGE_NAME}:latest"
    )
    
    # 如果指定了注册表，添加注册表前缀
    if [[ -n "${REGISTRY}" ]]; then
        for i in "${!tags[@]}"; do
            tags[i]="${REGISTRY}/${tags[i]}"
        done
    fi
    
    # 添加标签参数
    for tag in "${tags[@]}"; do
        build_args+=("--tag=${tag}")
    done
    
    # 添加推送参数（如果指定了注册表）
    if [[ -n "${REGISTRY}" ]]; then
        build_args+=("--push")
        log_info "将推送到注册表: ${REGISTRY}"
    else
        build_args+=("--load")
        log_info "将加载到本地Docker"
    fi
    
    # 执行构建
    log_info "执行构建命令..."
    echo "docker buildx build ${build_args[*]} ."
    
    if docker buildx build "${build_args[@]}" .; then
        log_success "多架构镜像构建成功"
    else
        log_error "镜像构建失败"
        exit 1
    fi
}

# 验证镜像
verify_images() {
    log_info "验证构建的镜像..."
    
    for tag in "${IMAGE_NAME}:${VERSION}" "${IMAGE_NAME}:latest"; do
        if [[ -n "${REGISTRY}" ]]; then
            tag="${REGISTRY}/${tag}"
        fi
        
        log_info "检查镜像: ${tag}"
        
        if [[ -z "${REGISTRY}" ]]; then
            # 本地镜像验证
            if docker image inspect "${tag}" &> /dev/null; then
                local size=$(docker image inspect "${tag}" --format='{{.Size}}' | numfmt --to=iec)
                log_success "镜像存在: ${tag} (大小: ${size})"
            else
                log_error "镜像不存在: ${tag}"
            fi
        else
            # 远程镜像验证
            if docker manifest inspect "${tag}" &> /dev/null; then
                log_success "远程镜像存在: ${tag}"
            else
                log_error "远程镜像不存在: ${tag}"
            fi
        fi
    done
}

# 生成镜像清单
generate_manifest() {
    log_info "生成镜像清单..."
    
    local manifest_file="${PROJECT_ROOT}/docker/image-manifest.json"
    
    cat > "${manifest_file}" << EOF
{
  "name": "LingShu Message Queue",
  "version": "${VERSION}",
  "build_date": "${BUILD_DATE}",
  "git_commit": "${GIT_COMMIT}",
  "platforms": [
$(echo "${PLATFORMS}" | sed 's/,/",\n    "/g' | sed 's/^/    "/' | sed 's/$/"/')
  ],
  "images": [
    {
      "tag": "${IMAGE_NAME}:${VERSION}",
      "target": "${BUILD_TARGET}",
      "size": "TBD"
    },
    {
      "tag": "${IMAGE_NAME}:latest",
      "target": "${BUILD_TARGET}",
      "size": "TBD"
    }
  ],
  "registry": "${REGISTRY:-"local"}",
  "dockerfile": "${DOCKERFILE}",
  "build_args": {
    "VERSION": "${VERSION}",
    "BUILD_DATE": "${BUILD_DATE}",
    "GIT_COMMIT": "${GIT_COMMIT}"
  }
}
EOF
    
    log_success "镜像清单已生成: ${manifest_file}"
}

# 清理构建器
cleanup_buildx() {
    log_info "清理构建器..."
    
    BUILDER_NAME="lingshu-builder"
    
    if docker buildx ls | grep -q "${BUILDER_NAME}"; then
        docker buildx rm "${BUILDER_NAME}" || true
        log_success "构建器已清理"
    fi
}

# 显示帮助信息
show_help() {
    cat << EOF
LingShu 多架构Docker镜像构建脚本

用法: $0 [选项]

选项:
  -h, --help              显示此帮助信息
  -v, --version VERSION   设置镜像版本 (默认: 1.0.0)
  -r, --registry REGISTRY 设置镜像注册表
  -p, --platforms PLATFORMS 设置目标平台 (默认: linux/amd64,linux/arm64,linux/arm/v7)
  -t, --target TARGET     设置构建目标 (默认: production)
  -f, --file DOCKERFILE   设置Dockerfile路径 (默认: Dockerfile.optimized)
  --push                  构建后推送到注册表
  --no-cache              不使用构建缓存
  --cleanup               构建后清理构建器

环境变量:
  VERSION                 镜像版本
  REGISTRY                镜像注册表
  PLATFORMS               目标平台
  BUILD_TARGET            构建目标
  DOCKERFILE              Dockerfile路径

示例:
  $0                                          # 构建默认配置
  $0 -v 2.0.0 -r docker.io/lingshu          # 指定版本和注册表
  $0 -p linux/amd64 -t development          # 只构建AMD64开发版
  $0 --push --cleanup                        # 构建、推送并清理

EOF
}

# 解析命令行参数
parse_args() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit 0
                ;;
            -v|--version)
                VERSION="$2"
                shift 2
                ;;
            -r|--registry)
                REGISTRY="$2"
                shift 2
                ;;
            -p|--platforms)
                PLATFORMS="$2"
                shift 2
                ;;
            -t|--target)
                BUILD_TARGET="$2"
                shift 2
                ;;
            -f|--file)
                DOCKERFILE="$2"
                shift 2
                ;;
            --push)
                PUSH_IMAGES=true
                shift
                ;;
            --no-cache)
                NO_CACHE=true
                shift
                ;;
            --cleanup)
                CLEANUP_AFTER=true
                shift
                ;;
            *)
                log_error "未知参数: $1"
                show_help
                exit 1
                ;;
        esac
    done
}

# 主函数
main() {
    parse_args "$@"
    
    show_banner
    check_dependencies
    setup_buildx
    
    build_images
    verify_images
    generate_manifest
    
    if [[ "${CLEANUP_AFTER:-false}" == "true" ]]; then
        cleanup_buildx
    fi
    
    log_success "多架构镜像构建完成！"
    echo
    echo "构建的镜像:"
    echo "  ${IMAGE_NAME}:${VERSION}"
    echo "  ${IMAGE_NAME}:latest"
    echo
    echo "支持的架构: ${PLATFORMS}"
    echo "构建目标: ${BUILD_TARGET}"
    
    if [[ -n "${REGISTRY}" ]]; then
        echo "注册表: ${REGISTRY}"
    fi
}

# 捕获退出信号
trap 'log_error "构建被中断"; exit 1' INT TERM

# 执行主函数
main "$@"
